<template>
  <div class="dashboard-container">
    <el-card>

      <!-- //^添加角色按钮 -->
      <el-row>
        <el-col>
          <el-button type="primary" @click="addDialogVisible = true">添加角色</el-button>
        </el-col>
      </el-row>

      <!-- //^表格 -->
      <el-table
        :data="rolesData"
        style="width: 100%"
        :border="true"
      >
        <el-table-column type="expand">
          <template v-slot="scope">
            <el-row v-for="(item) in scope.row.children" :key="item.id" class="bdtop vcenter">
              <el-col :span="8">
                <el-tag>
                  {{ item.authName }}
                </el-tag>
                <i class="el-icon-caret-right" />
              </el-col>
              <el-col :span="16">
                <el-row v-for="item1 in item.children" :key="item1.id" class="vcenter bdbottom">
                  <el-col :span="6">
                    <el-tag type="success">
                      {{ item1.authName }}
                    </el-tag>
                    <i class="el-icon-caret-right" />
                  </el-col>
                  <el-col :span="18">
                    <el-tag v-for="item2 in item1.children" :key="item2.id" type="warning" closable @close="removeTag(scope.row, item2.id)">
                      {{ item2.authName }}
                    </el-tag>
                    <i class="el-icon-caret-right" />
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column
          label="#"
          type="index"
        />
        <el-table-column
          label="角色名称"
          prop="roleName"
        />
        <el-table-column
          label="角色描述"
          prop="roleDesc"
        />
        <el-table-column
          label="操作"
          prop="desc"
        >
          <template v-slot="scope">
            <!-- 修改按钮 -->
            <!--size 大小属性-->
            <el-button type="primary" icon="el-icon-edit" size="mini" @click="editRoles(scope.row.id)">编辑</el-button>
            <!-- 删除按钮 -->
            <el-button type="danger" icon="el-icon-delete" size="mini" @click="delRoles(scope.row.id)">删除</el-button>
            <!-- 分配角色按钮 -->
            <el-button type="warning" icon="el-icon-setting" size="mini" @click="allotRoles(scope.row)">分配权限</el-button>
          </template>
        </el-table-column>
      </el-table>

    </el-card>

    <!-- //^编辑角色弹出框 -->
    <el-dialog
      title="提示"
      :visible.sync="editDialogVisible"
      width="50%"
      @close="editDialogClosed"
    >
      <el-form ref="editform" :model="roles" label-width="80px" :rules="rules">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roles.roleName" />
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="roles.roleDesc" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="upDateRoles">确 定</el-button>
      </span>
    </el-dialog>

    <!-- //^添加角色弹出框 -->
    <el-dialog
      title="提示"
      :visible.sync="addDialogVisible"
      width="50%"
      @close="addDialogClosed"
    >
      <el-form ref="addform" :model="addroles" label-width="80px" :rules="addrules">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="addroles.roleName" />
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="addroles.roleDesc" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addRolesData">确 定</el-button>
      </span>
    </el-dialog>

    <!-- //^分配权限弹出框 -->
    <el-dialog title="分配权限" :visible.sync="allotDialogVisible" width="50%" @close="allotDialogClosed">
      <!-- 树形控件 -->
      <!--
            show-checkbox:显示复选框
            node-key:设置选中节点对应的值
            default-expand-all:是否默认展开所有节点
            :default-checked-keys 设置默认选中项的数组
            ref:设置引用
       -->
      <el-tree ref="treeRef" :data="allotlist" :props="treeProps" show-checkbox node-key="id" default-expand-all :default-checked-keys="defKeys" />
      <span slot="footer" class="dialog-footer">
        <el-button @click="allotDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="allotRolesData">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
import {
  getRolesList,
  delRolesRights,
  delRoles,
  getRolesById,
  upDateRoles,
  addDateRoles,
  impowerRoles
} from '@/api/roles'

import { getRightList } from '@/api/rights'

export default {
  data() {
    return {
      // 角色列表
      rolesData: [],

      // ^编辑角色
      // 编辑角色弹出框
      editDialogVisible: false,
      // 获取单个角色
      roles: {},
      // 规则
      rules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        roleDesc: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ]
      },

      // ^添加角色
      // 编辑角色弹出框
      addDialogVisible: false,
      // 角色信息
      addroles: {},
      // 规则
      addrules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        roleDesc: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ]
      },

      // ^分配权限
      // 弹出框
      allotDialogVisible: false,
      // 所有权限的数据
      allotlist: [],
      // 树形控件的属性绑定对象
      treeProps: {
        label: 'authName',
        children: 'children'
      },
      // 默认选中的节点Id值数组
      defKeys: [],
      // 当前即将分配权限的角色id
      roleId: ''
    }
  },

  created() {
    this.getRolesList()
  },

  methods: {
    // ^获取角色列表
    async getRolesList() {
      const res = await getRolesList()
      // console.log(res)
      this.rolesData = res
    },
    // ^删除tag权限
    async removeTag(obj, id) {
      // console.log(obj)
      // console.log(id)
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async() => {
          const res = await delRolesRights(obj.id, id)
          // console.log(res)
          this.$message.success('删除权限成功')
          // this.getRolesList()
          // 不用重新获取，刷新页面，重新赋值即可
          // eslint-disable-next-line require-atomic-updates
          obj.children = [...res]
        })
        .catch(() => {})
    },
    // ^删除角色
    delRoles(id) {
      console.log(id)
      this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async() => {
          await delRoles(id)
          // console.log(res)
          this.$message.success('删除角色成功')
          this.getRolesList()
        })
        .catch(() => {})
    },

    // ^编辑角色
    // 点击按钮
    async editRoles(id) {
      // console.log(id)
      const res = await getRolesById(id)
      console.log(res)
      this.roles = res
      this.editDialogVisible = true
    },
    // 监听修改用户对话框的关闭事件
    editDialogClosed() {
      // 对话框关闭之后，重置表达
      this.$refs.editform.resetFields()
    },
    // 编辑提交角色
    upDateRoles() {
      this.$refs.editform.validate(async valid => {
        // 验证没有通过
        if (!valid) return this.$message.error('请填写完整用户信息')
        try {
          // 可以发起添加用户的网络请求
          await upDateRoles(
            this.roles.roleId,
            this.roles.roleName,
            this.roles.roleDesc
          )
          // console.log(res)
          this.$message.success('编辑提交角色成功')
          // 隐藏修改用户的对话框
          this.editDialogVisible = false
          // 重新获取用户列表数据
          this.getRolesList()
        } catch (err) {
          this.$message.error('编辑提交角色失败')
        }
      })
    },

    // ^添加角色
    // 监听添加角色对话框的关闭事件
    addDialogClosed() {
      // 对话框关闭之后，重置表达
      this.$refs.addform.resetFields()
    },
    // 确定添加角色
    addRolesData() {
      this.$refs.addform.validate(async valid => {
        // console.log(valid)
        if (!valid) return this.$message.error('请填写完整角色信息')
        // 可以发起添加用户的网络请求
        try {
          await addDateRoles(this.addroles)
          this.$message.success('添加角色成功')
        } catch (err) {
          this.$message.error('添加角色失败')
        }
        // 隐藏添加用户的对话框
        this.addDialogVisible = false
        // 重新获取用户列表数据
        this.getRolesList()
      })
    },

    // ^分配权限
    // 分配权限按钮
    async allotRoles(obj) {
      this.allotDialogVisible = true
      // console.log(obj)
      this.roleId = obj.id
      // 获取所有权限列表
      const res = await getRightList('tree')
      // console.log(res)
      // 把获取到的权限数据保存到 data 中
      this.allotlist = res
      this.transListToTree(obj, this.defKeys)
    },
    // 封装获取id值得方法// 递归的用法
    transListToTree(data, arr) {
      // 判断当前是否有children节点，没有就直接添加id?
      if (!data.children) return arr.push(data.id)
      // 如果有children节点，就循环递归
      data.children.forEach(item => this.transListToTree(item, this.defKeys))
    },
    // 监听分配权限对话框的关闭事件
    allotDialogClosed() {
      this.defKeys = []
    },
    // 确定按钮
    async allotRolesData() {
      // 若节点可被选择（即 show-checkbox 为 true），则返回目前被选中的节点的 key 所组成的数组
      // console.log(this.$refs.treeRef.getCheckedKeys())
      // // 若节点可被选择（即 show-checkbox 为 true），则返回目前半选中的节点的 key 所组成的数组
      // console.log(this.$refs.treeRef.getHalfCheckedKeys())
      const data = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ].join(',')
      try {
        await impowerRoles(this.roleId, data)
        this.$message.success('分配权限成功')
        this.allotDialogVisible = false
        this.getRolesList()
      } catch (err) {
        this.$message.error('分配权限失败')
      }
    }
  }
}
</script>

<style scoped lang='less'>
.el-table {
  margin-top: 15px;
}
.el-tag {
  margin: 7px;
}
.bdtop {
  border-top: 1px solid #eee;
}

.bdbottom {
  border-bottom: 1px solid #eee;
}

.vcenter {
  display: flex;
  align-items: center;
}
</style>
